﻿using FreeRedis;
using FreeSql;
using Masuit.Tools;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Simple.Common.Helpers;
using Simple.Contracts.Contracts;
using Simple.Contracts.Models;
using Simple.Contracts.Models.Common;
using Simple.Repository;
using Simple.Repository.SimpleEntitys;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Simple.Services.Services
{
    /// <summary>
    /// 账号相关
    /// </summary>
    public class AccountService : BaseService, IAccountService
    {
        private readonly IRedisService _redisService;
        private readonly ISmsService _smsService;

        public AccountService(FreeSqlCloud freeSqlCloud, IRedisService redisService, CurrentAccount currentAccount, ISmsService smsService) : base(freeSqlCloud, currentAccount)
        {
            _redisService = redisService;
            _smsService = smsService;
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Result<LoginDto>> Login(LoginInput input)
        {
            // 验证员工信息
            var passWordCiphertext = MD5Helper.GetMd5HashLowercase(input.password);
            var employee = await _simpleFreeSql.Select<Employee>().Where(x => input.username == x.Phone && passWordCiphertext == x.Password).FirstAsync();
            if (employee == null)
            {
                return Result<LoginDto>.FriendlyReminder("密码不正确");
            }

            // 验证公司信息
            var company = await _simpleFreeSql.Select<Company>().Where(x => x.Id == employee.CompanyId && x.IsDelete == 0).FirstAsync();
            if (company == null)
            {
                return Result<LoginDto>.FriendlyReminder("公司主体不存在");
            }
            if (company.VersionExpiryTime < DateTime.Now)
            {
                return Result<LoginDto>.FriendlyReminder("您购买的系统版本已过期,请联系平台续费");
            }

            // 准备权限
            var employeePermissions = new List<string>();
            var employeeRoleIds = await _simpleFreeSql.Select<RoleEmployee>().Where(x => x.CompanyId == employee.CompanyId && x.EmployeeId == employee.Id && x.IsDelete == 0).ToListAsync(x => x.RoleId);
            if (employee.IsAdmin == 0)
            {
                var employeePermissionIds = await _simpleFreeSql.Select<RolePermission>().Where(x => x.CompanyId == employee.CompanyId && employeeRoleIds.Contains(x.RoleId) && x.IsDelete == 0).ToListAsync(x => x.PermissionId);
                employeePermissions = await _simpleFreeSql.Select<SysPermission>().Where(x => x.Version.Contains(company.Version + "√") && employeePermissionIds.Contains(x.Id)).ToListAsync(x => x.Name);
            }
            else
            {
                employeePermissions = await _simpleFreeSql.Select<SysPermission>().Where(x => x.Version.Contains(company.Version + "√")).ToListAsync(x => x.Name);
            }

            // 保存登录记录
            var token = Guid.NewGuid().ToString("N");
            int tokenTimeoutSeconds = 60 * 60 * 24 * 15;
            var EmployeeLoginLogEntity = new EmployeeLoginLogs()
            {
                CompanyId = company.Id,
                EmployeeId = employee.Id,
                EmployeeLoginTime = DateTime.Now,
                EmployeeToken = token,
                EmployeeTokenExpiredTime = DateTime.Now.AddSeconds(tokenTimeoutSeconds),
                IsLogout = 0
            };
            await _simpleFreeSql.Insert<EmployeeLoginLogs>(EmployeeLoginLogEntity).ExecuteAffrowsAsync();

            // 返回当前用户信息
            var data = new LoginDto()
            {
                access_token = token,
                userInfo = new CurrentAccount()
                {
                    CompanyId = employee.CompanyId,
                    CompanyName = company.Name,
                    CompanyVersion = company.Version,
                    CompanyVersionExpiryTime = company.VersionExpiryTime,
                    EmployeeId = employee.Id,
                    EmployeeName = employee.Name,
                    EmployeePhone = employee.Phone,
                    EmployeeIsAdmin = employee.IsAdmin == 1,
                    EmployeeRoleIds = employeeRoleIds,
                    EmployeePermissions = employeePermissions
                }
            };

            // 保存到Redis
            _redisService.SetAccountLoginToken(token,JsonConvert.SerializeObject(data.userInfo), employee.CompanyId, employee.Id, tokenTimeoutSeconds);

            return Result<LoginDto>.Success(data);
        }

        /// <summary>
        /// 菜单权限
        /// </summary>
        /// <returns></returns>
        public async Task<Result<List<MenuPageDto>>> MenuPageList()
        {
            var data = new List<MenuPageDto>();

            // 不是管理员，需要验证权限
            var permissionIds = new List<long>();
            if (!_currentAccount.EmployeeIsAdmin)
            {
                permissionIds = await _simpleFreeSql.Select<RolePermission>().Where(x => x.CompanyId == _currentAccount.CompanyId && _currentAccount.EmployeeRoleIds.Contains(x.RoleId)).ToListAsync(x => x.PermissionId);
            }

            // 获取菜单权限
            var menuPageList = await _simpleFreeSql.Select<SysPermission>()
                .Where(x => x.Version.Contains(_currentAccount.CompanyVersion + "√") && (x.Type == "菜单权限" || x.Type == "页面权限"))
                .WhereIf(!_currentAccount.EmployeeIsAdmin, x => permissionIds.Contains(x.Id))
                .ToListAsync();

            foreach (var item1 in menuPageList.Where(x => x.ParentId == 0).OrderBy(x => x.Sort))
            {
                var menuPage = new MenuPageDto()
                {
                    children = new List<MenuPageDto>(),
                    component = item1.Component,
                    meta = new MenuPageMetaDto()
                    {
                        icon = item1.Icon,
                        isAffix = item1.IsAffix == 1,
                        isFull = item1.IsFull == 1,
                        isHide = item1.IsHide == 1,
                        isKeepAlive = item1.IsKeepAlive == 1,
                        isLink = item1.IsLink,
                        title = item1.Title,
                    },
                    name = item1.Name,
                    path = item1.Path,
                };
                foreach (var item2 in menuPageList.Where(x => x.ParentId == item1.Id).OrderBy(x => x.Sort))
                {
                    menuPage.children.Add(new MenuPageDto()
                    {
                        children = new List<MenuPageDto>(),
                        component = item2.Component,
                        meta = new MenuPageMetaDto()
                        {
                            icon = item2.Icon,
                            isAffix = item2.IsAffix == 1,
                            isFull = item2.IsFull == 1,
                            isHide = item2.IsHide == 1,
                            isKeepAlive = item2.IsKeepAlive == 1,
                            isLink = item2.IsLink,
                            title = item2.Title,
                        },
                        name = item2.Name,
                        path = item2.Path,
                    });
                }
                if (menuPage.children.Any())
                {
                    menuPage.redirect = menuPage.children[0].path;
                }

                data.Add(menuPage);
            }
            return Result<List<MenuPageDto>>.Success(data);
        }

        /// <summary>
        /// 功能权限
        /// </summary>
        /// <returns></returns>
        public async Task<Result<Dictionary<string, List<string>>>> AuthButtons()
        {
            var data = new Dictionary<string, List<string>>();
            var permissionIds = new List<long>();
            if (!_currentAccount.EmployeeIsAdmin)
            {
                permissionIds = await _simpleFreeSql.Select<RolePermission>()
                    .Where(x => x.CompanyId == _currentAccount.CompanyId && _currentAccount.EmployeeRoleIds.Contains(x.RoleId))
                    .ToListAsync(x => x.PermissionId);
            }
            var menuPageList = await _simpleFreeSql.Select<SysPermission>()
                .Where(x => x.Version.Contains(_currentAccount.CompanyVersion + "√") && (x.Type == "功能权限" || x.Type == "页面权限"))
                .WhereIf(!_currentAccount.EmployeeIsAdmin, x => permissionIds.Contains(x.Id))
                .ToListAsync();

            foreach (var item in menuPageList.Where(x => x.Type == "页面权限"))
            {
                var list = menuPageList.Where(x => x.ParentId == item.Id).Select(x => x.Name).ToList();
                data.Add(item.Name, list);
            }
            return Result<Dictionary<string, List<string>>>.Success(data);
        }

        /// <summary>
        /// 发送登录验证码
        /// </summary>
        /// <param name="phone"></param>
        /// <returns></returns>
        public async Task<Result<bool>> SendLoginCode(string phone)
        {
            var code = RandomHelper.GenerateNumericPassword(6);
            _redisService.SetLoginCodeKey(phone, code);
            await _smsService.SendLoginCode(phone, code);
            return Result<bool>.Success(true);
        }
    }
}